总览
尝试在mac中编译openjdk,也尝试过在mac上装linux虚拟机编译openjdk,但是每次都不顺利,比如mac每次都是c++编译环境苹果擅自改成clang之后,openjdk编译会产生很多奇怪的编译问题,一旦失败再重新开始需要重装系统还挺麻烦的,现在用docker就省事很多了,镜像和容器的创建和删除都比较简单干净,专心做好Dockerfile就行,下面我们一起来实践一下吧。
本次编译实战的基本步骤如下:
编写的Dockerfile
编写的Dockerfile中要做的如下的事情:
- 安装依赖的软件;
- 把openjdk的源码复制到镜像中; 在编写Dockerfile之前要做三个重要的选择,如下:
- linux:我选择了centos7
- openjdk源码,这次要编译的是openjdk8
- Bootstrap JDK 下载了openjdk的源码后,解压开可以看到“README-builds.html”这个文件,里面有对Bootstrap JDK的描述
Building JDK 8 requires use of a version of JDK 7 that is at Update 7 or newer. JDK 8 developers should not use JDK 8 as the boot JDK, to ensure that JDK 8 dependencies are not introduced into the parts of the system that are built with JDK 7.
看得出,需要安装jdk7来编译openjdk8的源码,这里也可以选择jdk8,以为我本机有jdk8之后就选用了jdk8;
OK,关键问题都已确认,即将开始Dockerfile制作,不过制作之前还有个小问题需要先想好:本次我打算把制作镜像所需的Dockerfile和依赖文件都放到github上去,这样做的好处有两个:
- 读者们从git上clone下来之后直接执行Docker build就能在本地构建镜像;
- daocloud.io网站上支持通过执行github目录的方式在线构建镜像,后面我们会实践在daocloud.io上构建镜像并部署到腾讯云或者阿里云服务器上;
上传到github时,除了Dockerfile,还要上传的文件有两个:jdk1.7和openjdk8源码,都超过了100M,这里采用mac自带的split函数分割为50m的文件,再用cat函数在docker 中合并为单个文件
split -b 50m jdk-8u231-linux-x64.rpm jdkrpm-
split -b 50m openjdk8.zip openjdksrc-
Dockerfile中,从分割文件恢复以上两个原文件的命令为:
cat jdkrpm-* > jdk-8u231-linux-x64.rpm
cat openjdksrc-* > openjdk8.zip
好了,前期的准备工作已经做完了,现在可以编写Dockerfile文件了,整个文件中要做的事情列出如下:
- 安装依赖软件,例如libXtst-devel,libXt-devel等等,这些都是编译前的configure命令要检查的,检查不过无法进行编译;
- 把分割后的openjdk源码复制到镜像文件中,再合成,再解压;
- 安装jdk8,把分割后的安装文件复制到镜像中合成,然后安装;
- 为了方便用户进入容器后快速开始编译,我们做了一个shell脚本start_make.sh,把这个脚本也要复制到镜像中,内容如下:
#!/bin/bash
$WORK_PATH/$OPENJDK_SRC_DIR/configure
echo "start make"
cd $WORK_PATH/$OPENJDK_SRC_DIR
make all ZIP_DEBUGINFO_FILES=0 DISABLE_HOTSPOT_OS_VERSION_CHECK=OK
- 清理无用的文件,例如openjdk源码的压缩文件,jdk8的安装文件等; 按照以上步骤,最终写出的Dockerfile文件如下:
#基础镜像使用centos7
FROM centos:centos7
#作者
MAINTAINER yupingtao <m18227863155@163.com>
#定义工作目录
ENV WORK_PATH /usr/local
#定义jdk1.7的文件名
ENV JDK_RPM_FILE jdk-8u231-linux-x64.rpm
#定义openJdk源码的文件名
ENV OPENJDK_SRC_ZIP openjdk8.zip
#定义解压缩后的文件名
ENV OPENJDK_SRC_DIR openjdk
#yum更新
RUN yum -y update
#安装工具集
RUN yum -y groupinstall "Development Tools"
#安装即将用到的软件
RUN yum -y install unzip libXtst-devel libXt-devel libXrender-devel cups-devel freetype-devel alsa-lib-devel which
#把分割过的jdk1.7安装文件复制到工作目录
COPY ./jdkrpm-* $WORK_PATH/
#用本地分割过的文件恢复原有的jdk1.8的安装文件
RUN cat $WORK_PATH/jdkrpm-* > $WORK_PATH/$JDK_RPM_FILE
#本地安装jdk1.8
RUN yum -y localinstall $WORK_PATH/$JDK_RPM_FILE
#把分割过的openJdk8的源码压缩包复制到工作目录
COPY ./openjdksrc-* $WORK_PATH/
#用本地分割过的文件恢复原有的openJdk8的源码压缩包
RUN cat $WORK_PATH/openjdksrc-* > $WORK_PATH/$OPENJDK_SRC_ZIP
#解压缩源码
RUN unzip $WORK_PATH/$OPENJDK_SRC_ZIP -d $WORK_PATH/$OPENJDK_SRC_DIR
#复制启动编译的shell
COPY ./start_make.sh $WORK_PATH/$OPENJDK_SRC_DIR/
#给执行文件增加可执行权限:configure文件
RUN chmod a+x $WORK_PATH/$OPENJDK_SRC_DIR/configure
#给执行文件增加可执行权限:启动编译文件
RUN chmod a+x $WORK_PATH/$OPENJDK_SRC_DIR/start_make.sh
#删除分割文件
RUN rm $WORK_PATH/jdkrpm-*
#删除分割文件
RUN rm $WORK_PATH/openjdksrc-*
#删除jdk安装包文件
RUN rm $WORK_PATH/$JDK_RPM_FILE
#删除openJdk源码压缩文件
RUN rm $WORK_PATH/$OPENJDK_SRC_ZIP
构建镜像
至此,镜像文件制作所需的材料都已经齐全了,如下图:
现在让我们开始制作镜像吧,打开终端,进入Dockerfile所在目录,执行命令
docker build -t bolingcavalryopenjdk:0.0.1 .
因为要在线安装不少的软件,所以可能耗时会略长,和网络带宽有关,我在住处用家庭网络大概10分钟左右构建成功,执行目录docker
images查看镜像,新的镜像文件已经生成了,如下图:
启动容器
现在启动一个容器试试吧:
docker run --name=jdk001 -idt bolingcavalryopenjdk:0.0.1
编译OpenJDK源码
容器已经启动,再执行以下命令进入容器:
docker exec -it jdk001 /bin/bash
进去后,直接到/usr/local/openjdk目录下,执行./start_make.sh,开始编译了,整个过程的耗时和当前电脑的硬件配置有关,我用i7处理器的mac pro18大约要用20多分钟,编译结束后会有类似下图的输出:
这时候去/usr/local/openjdk目录下看看,发现多了一个build目录,这里面就是编译好的结果,如下图:
build目录下只有一个linux-x86_64-normal-server-release目录,再进去就能看到jdk目录了,如下图:
进入/usr/local/openjdk/build/linux-x86_64-normal-server-release/jdk/bin目录,会发现里面有java文件,执行./java -version输出如下:
新的jdk信息已经打印出来了,OpenJDK Runtime Enviroment信息已经说明了这是个最新构建的jdk环境。
最后:分享一波我的附件地址